﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Web;
using System.IO;

namespace MZaki.CustomActions
{
    public class DownloadZippedItems :WebControl
    {
        protected override void OnLoad(EventArgs e)
        {
            this.EnsureChildControls();
            base.OnLoad(e);
        }
        protected override void  CreateChildControls()
        {
           
            if (!this.ChildControlsCreated)
            {
                base.CreateChildControls();

                // Create the sub menu item
                SubMenuTemplate mnuZipListItems = new SubMenuTemplate();
                mnuZipListItems.Text = "Zip List Items";
                mnuZipListItems.ImageUrl = "/_layouts/images/TBSPRSHT.GIF";
                mnuZipListItems.Description = "Zip and download List Items";
                //mnuZipListItems.ID = "downloadZipped";

                //Add zip and download all 
                PostBackMenuItemTemplate mnuListItem = new PostBackMenuItemTemplate();
                mnuListItem.ID = "menu1";
                mnuListItem.Text = "All Items";
                //mnuListItem.ID = "mymenulistitemid";
                mnuListItem.Description = "Zip and Download All Items";
                mnuListItem.ClientOnClickPostBackConfirmation = "You will download all list items, depending on the items count and size it might take some time,are you sure ?";

                mnuListItem.OnPostBack += new EventHandler<EventArgs>(mnuListItem_OnPostBack);


                //Add zip and download all with versions
                PostBackMenuItemTemplate mnuListItem2 = new PostBackMenuItemTemplate();
                mnuListItem2.Text = "All Items with Versions";
                mnuListItem2.Description = "Zip and Download All Items";
                mnuListItem2.ID = "menu2";
                mnuListItem2.OnPostBack += new EventHandler<EventArgs>(mnuListItem2_OnPostBack);
                mnuListItem2.ClientOnClickPostBackConfirmation = "You will download all list items, depending on the items count and size it might take some time,are you sure ?";

              

                //Separator
                MenuSeparatorTemplate separator = new MenuSeparatorTemplate();

                //Current View only
                PostBackMenuItemTemplate mnuListItemCurrentView = new PostBackMenuItemTemplate();
                mnuListItemCurrentView.Text = "Items In Current View";
                mnuListItemCurrentView.Description = "Zip and Download All Items";
                mnuListItemCurrentView.ID = "menu3";
                mnuListItemCurrentView.OnPostBack += new EventHandler<EventArgs>(mnuListItemCurrentView_OnPostBack);


                //Current View only with versions
                PostBackMenuItemTemplate mnuListItemCurrentViewVersions = new PostBackMenuItemTemplate();
                mnuListItemCurrentViewVersions.Text = "Items In Current View With Versions";
                mnuListItemCurrentViewVersions.Description = "Zip and Download All Items";
                mnuListItemCurrentViewVersions.ID = "menu4";
                mnuListItemCurrentViewVersions.OnPostBack += new EventHandler<EventArgs>(mnuListItemCurrentViewVersions_OnPostBack);

                

                mnuZipListItems.Controls.Add(mnuListItem);
                mnuZipListItems.Controls.Add(mnuListItem2);
                
                mnuZipListItems.Controls.Add(separator);
                mnuZipListItems.Controls.Add(mnuListItemCurrentView);
                mnuZipListItems.Controls.Add(mnuListItemCurrentViewVersions);

                this.Controls.Add(mnuZipListItems);
                
            }
        }






        #region Postback Events

        void mnuListItem2_OnPostBack(object sender, EventArgs e)
        {
            GetListItems(SPContext.Current.List.ID, true, false);
        }
        void mnuListItem_OnPostBack(object sender, EventArgs e)
        {

                GetListItems(SPContext.Current.List.ID, false, false);
        }
        void mnuListItemCurrentView_OnPostBack(object sender, EventArgs e)
        {
            GetListItems(SPContext.Current.List.ID, false, true);

        }
        void mnuListItemCurrentViewVersions_OnPostBack(object sender, EventArgs e)
        {
            GetListItems(SPContext.Current.List.ID, true, true);

        }
        #endregion

        #region Private Methods
        void GetListItems(Guid listId, bool IncludeVersions,bool isCurrentView)
        {

            //Create a temp directory
            string strTempDirectory = Path.GetTempPath();
            string strTempFolder = Path.GetRandomFileName();
            string tmpDirLocation = strTempDirectory + strTempFolder + "\\";

            if (!Directory.Exists(tmpDirLocation))
                System.IO.Directory.CreateDirectory(tmpDirLocation);
            

            SPList list;
            // SPWeb web;

            list = SPContext.Current.Web.Lists[listId];
            SPListItemCollection listItems;

            //if working only with the current view items
            if (isCurrentView)
            {
                SPView currentView= SPContext.Current.ViewContext.View;
                //listItems = list.GetItems(currentView);

                //new technique
                SPQuery query = new SPQuery();
                query.Query = currentView.Query;

                //Get Items in subfolders as well
                query.ViewAttributes=" Scope=\"Recursive\"";
                listItems= list.GetItems(query);
            
            }
            else
            {
                listItems = list.Items;

            }
            

           
            foreach (SPListItem item in listItems )
            {
                

                byte[] bytFile;
                SPFile file = item.File;
                if (file != null)
                {
                    bytFile = file.OpenBinary();

                    string folder = file.ParentFolder.Name;
                    string fileRelativePath = file.ServerRelativeUrl;

                    //remove the first "/"
                    fileRelativePath = fileRelativePath.Remove(0, 1);
                    string filePath = fileRelativePath.Substring(fileRelativePath.IndexOf("/") + 1);

                    //Remove the filename 
                    string DirectoryPath = filePath.Replace(file.Name, "");

                    DirectoryPath = DirectoryPath.Replace("/", "\\");

                    //create the directory path
                    if (!string.IsNullOrEmpty(DirectoryPath))
                        Directory.CreateDirectory(tmpDirLocation + DirectoryPath);


                    string QualifiedFileName = tmpDirLocation + DirectoryPath + file.Name;

                    WriteToFile(bytFile, QualifiedFileName);

                    //if versions included enumerate the versions and export them
                    if (IncludeVersions && list.EnableVersioning)
                    {
                        SPFileVersionCollection versions = file.Versions;
                        foreach (SPFileVersion version in versions)
                        {
                            if (!version.IsCurrentVersion)
                            {
                                byte[] fileVersion = version.OpenBinary();
                                string VersionNameNoExt = QualifiedFileName.Substring(0, QualifiedFileName.LastIndexOf("."));
                                string FileExt = QualifiedFileName.Substring(QualifiedFileName.LastIndexOf(".") + 1);

                                string versionName = VersionNameNoExt + "(" + version.VersionLabel + ")." + FileExt;

                                WriteToFile(fileVersion, versionName);

                            }

                        }

                    }
                }

            }

            //Compress the files
            string strZippedFile = strTempFolder + ".zip";
            ZipUtilities.ZipFiles(tmpDirLocation, strZippedFile, string.Empty);

            //Force the browser to download the file
            string FileName = list.Title + ".zip";
            PushFileToDownload(tmpDirLocation + strZippedFile, FileName);




        }
        bool WriteToFile(byte[] bytFile, string QualifiedFileName)
        {

            FileStream fs = new FileStream(QualifiedFileName, FileMode.OpenOrCreate, FileAccess.Write);
            fs.Write(bytFile, 0, bytFile.Length);
            fs.Close();
            return true;

        }
        void PushFileToDownload(string FilePath,string FileName)
        {
            FileInfo fInfo = new FileInfo(FilePath);
            HttpContext.Current.Response.ContentType = "application/x-download";
            HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment; filename=" + FileName);
            HttpContext.Current.Response.AddHeader("Content-Length", fInfo.Length.ToString());
            HttpContext.Current.Response.WriteFile(FilePath);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.End();
           

            
        }

        #endregion

    }
}
